/*帮忙写一个rgb lcd测试程序, 使用rt_thread的驱动框架接口*/

#include <rtthread.h>
#include <rtdevice.h>
#include <drivers/classes/graphic.h>

/* LCD设备名称 */
#define LCD_DEVICE_NAME    "lcd0"

/* 定义RGB565颜色格式 */
#define RGB565(r, g, b)    (((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3))

/* 预定义一些颜色 */
#define COLOR_BLACK        RGB565(0, 0, 0)
#define COLOR_WHITE        RGB565(255, 255, 255)
#define COLOR_RED          RGB565(255, 0, 0)
#define COLOR_GREEN        RGB565(0, 255, 0)
#define COLOR_BLUE         RGB565(0, 0, 255)
#define COLOR_YELLOW       RGB565(255, 255, 0)
#define COLOR_CYAN         RGB565(0, 255, 255)
#define COLOR_MAGENTA      RGB565(255, 0, 255)

/* 全局变量 */
static rt_device_t lcd_device = RT_NULL;
static struct rt_device_graphic_info lcd_info;

/* 声明测试函数 */
static rt_err_t lcd_init(void);
static void lcd_clear_screen(rt_uint16_t color);
static void lcd_draw_color_bar(void);
static void lcd_draw_grid(void);
static void lcd_draw_circle(rt_uint16_t center_x, rt_uint16_t center_y, rt_uint16_t radius, rt_uint16_t color);
static void lcd_draw_rectangle(rt_uint16_t x, rt_uint16_t y, rt_uint16_t width, rt_uint16_t height, rt_uint16_t color);
static void lcd_draw_line(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2, rt_uint16_t color);
static void lcd_test_patterns(void);

/* LCD初始化 */
static rt_err_t lcd_init(void)
{
    /* 查找LCD设备 */
    lcd_device = rt_device_find(LCD_DEVICE_NAME);
    if (lcd_device == RT_NULL)
    {
        rt_kprintf("Failed to find LCD device: %s\n", LCD_DEVICE_NAME);
        return -RT_ERROR;
    }

    /* 打开设备 */
    if (rt_device_open(lcd_device, RT_DEVICE_FLAG_RDWR) != RT_EOK)
    {
        rt_kprintf("Failed to open LCD device\n");
        return -RT_ERROR;
    }

    /* 获取LCD设备信息 */
    rt_device_control(lcd_device, RTGRAPHIC_CTRL_GET_INFO, &lcd_info);

    rt_kprintf("LCD initialized: %dx%d, %d bpp\n", 
               lcd_info.width, lcd_info.height, lcd_info.bits_per_pixel);

    return RT_EOK;
}

/* 清屏函数 */
static void lcd_clear_screen(rt_uint16_t color)
{
    rt_uint16_t *framebuffer = (rt_uint16_t *)lcd_info.framebuffer;
    rt_uint32_t i, pixel_count = lcd_info.width * lcd_info.height;

    for (i = 0; i < pixel_count; i++)
    {
        framebuffer[i] = color;
    }

    /* 更新显示 */
    rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
}

/* 绘制彩色条纹 */
static void lcd_draw_color_bar(void)
{
    rt_uint16_t *framebuffer = (rt_uint16_t *)lcd_info.framebuffer;
    rt_uint16_t x, y;
    rt_uint16_t bar_width = lcd_info.width / 8;

    for (y = 0; y < lcd_info.height; y++)
    {
        for (x = 0; x < lcd_info.width; x++)
        {
            if (x < bar_width)
                framebuffer[y * lcd_info.width + x] = COLOR_BLACK;
            else if (x < 2 * bar_width)
                framebuffer[y * lcd_info.width + x] = COLOR_WHITE;
            else if (x < 3 * bar_width)
                framebuffer[y * lcd_info.width + x] = COLOR_RED;
            else if (x < 4 * bar_width)
                framebuffer[y * lcd_info.width + x] = COLOR_GREEN;
            else if (x < 5 * bar_width)
                framebuffer[y * lcd_info.width + x] = COLOR_BLUE;
            else if (x < 6 * bar_width)
                framebuffer[y * lcd_info.width + x] = COLOR_YELLOW;
            else if (x < 7 * bar_width)
                framebuffer[y * lcd_info.width + x] = COLOR_CYAN;
            else
                framebuffer[y * lcd_info.width + x] = COLOR_MAGENTA;
        }
    }

    /* 更新显示 */
    rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
}

/* 绘制网格 */
static void lcd_draw_grid(void)
{
    rt_uint16_t *framebuffer = (rt_uint16_t *)lcd_info.framebuffer;
    rt_uint16_t x, y;
    rt_uint16_t grid_size = 20;

    /* 先清屏为白色 */
    lcd_clear_screen(COLOR_WHITE);

    /* 绘制水平线 */
    for (y = 0; y < lcd_info.height; y += grid_size)
    {
        for (x = 0; x < lcd_info.width; x++)
        {
            framebuffer[y * lcd_info.width + x] = COLOR_BLACK;
        }
    }

    /* 绘制垂直线 */
    for (x = 0; x < lcd_info.width; x += grid_size)
    {
        for (y = 0; y < lcd_info.height; y++)
        {
            framebuffer[y * lcd_info.width + x] = COLOR_BLACK;
        }
    }

    /* 更新显示 */
    rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
}

/* 绘制圆形 */
static void lcd_draw_circle(rt_uint16_t center_x, rt_uint16_t center_y, rt_uint16_t radius, rt_uint16_t color)
{
    rt_uint16_t *framebuffer = (rt_uint16_t *)lcd_info.framebuffer;
    int x, y, r2;

    r2 = radius * radius;
    for (y = -radius; y <= radius; y++)
    {
        for (x = -radius; x <= radius; x++)
        {
            if (x * x + y * y <= r2)
            {
                int px = center_x + x;
                int py = center_y + y;
                if (px >= 0 && px < lcd_info.width && py >= 0 && py < lcd_info.height)
                {
                    framebuffer[py * lcd_info.width + px] = color;
                }
            }
        }
    }

    /* 更新显示 */
    rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
}

/* 绘制矩形 */
static void lcd_draw_rectangle(rt_uint16_t x, rt_uint16_t y, rt_uint16_t width, rt_uint16_t height, rt_uint16_t color)
{
    rt_uint16_t *framebuffer = (rt_uint16_t *)lcd_info.framebuffer;
    rt_uint16_t i, j;

    for (j = y; j < y + height && j < lcd_info.height; j++)
    {
        for (i = x; i < x + width && i < lcd_info.width; i++)
        {
            framebuffer[j * lcd_info.width + i] = color;
        }
    }

    /* 更新显示 */
    rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
}

/* 绘制直线 */
static void lcd_draw_line(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2, rt_uint16_t color)
{
    rt_uint16_t *framebuffer = (rt_uint16_t *)lcd_info.framebuffer;
    int dx = abs(x2 - x1);
    int dy = abs(y2 - y1);
    int sx = (x1 < x2) ? 1 : -1;
    int sy = (y1 < y2) ? 1 : -1;
    int err = dx - dy;
    int e2;

    while (1)
    {
        if (x1 >= 0 && x1 < lcd_info.width && y1 >= 0 && y1 < lcd_info.height)
        {
            framebuffer[y1 * lcd_info.width + x1] = color;
        }

        if (x1 == x2 && y1 == y2)
            break;

        e2 = 2 * err;
        if (e2 > -dy)
        {
            err -= dy;
            x1 += sx;
        }
        if (e2 < dx)
        {
            err += dx;
            y1 += sy;
        }
    }

    /* 更新显示 */
    rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
}

/* 测试图案 */
static void lcd_test_patterns(void)
{
    rt_uint16_t i;
    rt_uint16_t center_x = lcd_info.width / 2;
    rt_uint16_t center_y = lcd_info.height / 2;
    rt_uint16_t radius = (lcd_info.width < lcd_info.height ? lcd_info.width : lcd_info.height) / 4;

    /* 1. 清屏为黑色 */
    rt_kprintf("Test 1: Clear screen to black\n");
    lcd_clear_screen(COLOR_BLACK);
    rt_thread_mdelay(1000);

    /* 2. 清屏为白色 */
    rt_kprintf("Test 2: Clear screen to white\n");
    lcd_clear_screen(COLOR_WHITE);
    rt_thread_mdelay(1000);

    /* 3. 绘制彩色条纹 */
    rt_kprintf("Test 3: Draw color bars\n");
    lcd_draw_color_bar();
    rt_thread_mdelay(2000);

    /* 4. 绘制网格 */
    rt_kprintf("Test 4: Draw grid\n");
    lcd_draw_grid();
    rt_thread_mdelay(2000);

    /* 5. 绘制不同颜色的矩形 */
    rt_kprintf("Test 5: Draw rectangles\n");
    lcd_clear_screen(COLOR_WHITE);
    lcd_draw_rectangle(10, 10, 100, 80, COLOR_RED);
    lcd_draw_rectangle(120, 10, 100, 80, COLOR_GREEN);
    lcd_draw_rectangle(230, 10, 100, 80, COLOR_BLUE);
    rt_thread_mdelay(2000);

    /* 6. 绘制不同颜色的圆形 */
    rt_kprintf("Test 6: Draw circles\n");
    lcd_clear_screen(COLOR_BLACK);
    lcd_draw_circle(center_x, center_y, radius, COLOR_RED);
    rt_thread_mdelay(500);
    lcd_draw_circle(center_x, center_y, radius - 20, COLOR_GREEN);
    rt_thread_mdelay(500);
    lcd_draw_circle(center_x, center_y, radius - 40, COLOR_BLUE);
    rt_thread_mdelay(2000);

    /* 7. 绘制线条 */
    rt_kprintf("Test 7: Draw lines\n");
    lcd_clear_screen(COLOR_WHITE);
    for (i = 0; i < lcd_info.width; i += 20)
    {
        lcd_draw_line(0, 0, i, lcd_info.height, COLOR_RED);
        lcd_draw_line(lcd_info.width, 0, i, lcd_info.height, COLOR_GREEN);
        lcd_draw_line(0, lcd_info.height, i, 0, COLOR_BLUE);
        lcd_draw_line(lcd_info.width, lcd_info.height, i, 0, COLOR_MAGENTA);
    }
    rt_thread_mdelay(2000);

    /* 8. 绘制渐变色 */
    rt_kprintf("Test 8: Draw gradient\n");
    {
        rt_uint16_t *framebuffer = (rt_uint16_t *)lcd_info.framebuffer;
        rt_uint16_t x, y;
        rt_uint16_t r, g, b;

        for (y = 0; y < lcd_info.height; y++)
        {
            for (x = 0; x < lcd_info.width; x++)
            {
                r = (x * 255) / lcd_info.width;
                g = (y * 255) / lcd_info.height;
                b = 128;
                framebuffer[y * lcd_info.width + x] = RGB565(r, g, b);
            }
        }
        rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
    }
    rt_thread_mdelay(2000);

    rt_kprintf("All tests completed!\n");

    while(1){
        rt_thread_mdelay(1000);
    }
}

/* LCD测试线程 */
static void lcd_test_thread_entry(void *parameter)
{
    /* 初始化LCD */
    if (lcd_init() != RT_EOK)
    {
        rt_kprintf("LCD initialization failed!\n");
        return;
    }

    /* 打开LCD背光 */
    rt_device_control(lcd_device, RTGRAPHIC_CTRL_POWERON, RT_NULL);

    /* 运行测试图案 */
    lcd_test_patterns();

    /* 关闭LCD背光 */
    rt_device_control(lcd_device, RTGRAPHIC_CTRL_POWEROFF, RT_NULL);

    /* 关闭设备 */
    rt_device_close(lcd_device);
}

int lcd_test(void)
{
    rt_thread_t tid;
    tid = rt_thread_create("lcd_test",
                           lcd_test_thread_entry,
                           RT_NULL,
                           2048,
                           RT_THREAD_PRIORITY_MAX / 2,
                           20);

    rt_thread_startup(tid);
}

INIT_APP_EXPORT(lcd_test);